home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / egem_200.lzh / EGEM.2_0 / SOURCE / OBJCEDIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-07  |  20.6 KB  |  983 lines

  1.  
  2. #include "proto.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6.  
  7. #ifndef __MINT_LIB__
  8. #include <stdlib.h>
  9. #endif
  10.  
  11. #define    te_editlen    te_junk1
  12.  
  13. #define    HISTORY    20
  14.  
  15. static char history[HISTORY][MAX_EDIT];
  16. static int    hist_index;
  17.  
  18. static char umlaute[] = "_äöüÄÖÜß";
  19.  
  20. static char string_0[] = "ASCII-Table";
  21. static char string_1[] = " \x01" "\x02" "\x03" "\x04" "\x05" "\x06" "\x07" "\x08" "\x09" "\x0a" "\x0b" "\x0c" "\x0d" "\x0e" "\x0f" "\x10" "\x11" "\x12" "\x13" "\x14" "\x15" "\x16" "\x17" "\x18" "\x19" "\x1a" "\x1b" "\x1c" "\x1d" "\x1e" "\x1f" "";
  22. static char string_2[] = " !\"#$%&\'()*+,-./0123456789:;<=>?";
  23. static char string_3[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
  24. static char string_4[] = "`abcdefghijklmnopqrstuvwxyz{|}~\x7f" "";
  25. static char string_5[] = "\x80" "ü\x82" "\x83" "ä\x85" "\x86" "\x87" "\x88" "\x89" "\x8a" "\x8b" "\x8c" "\x8d" "Ä\x8f" "\x90" "\x91" "\x92" "\x93" "ö\x95" "\x96" "\x97" "\x98" "ÖÜ\x9b" "\x9c" "\x9d" "ß\x9f" "";
  26. static char string_6[] = "\xa0" "\xa1" "\xa2" "\xa3" "\xa4" "\xa5" "\xa6" "\xa7" "\xa8" "\xa9" "\xaa" "\xab" "\xac" "\xad" "\xae" "\xaf" "\xb0" "\xb1" "\xb2" "\xb3" "\xb4" "\xb5" "\xb6" "\xb7" "\xb8" "\xb9" "\xba" "\xbb" "\xbc" "\xbd" "\xbe" "\xbf" "";
  27. static char string_7[] = "\xc0" "\xc1" "\xc2" "\xc3" "\xc4" "\xc5" "\xc6" "\xc7" "\xc8" "\xc9" "\xca" "\xcb" "\xcc" "\xcd" "\xce" "\xcf" "\xd0" "\xd1" "\xd2" "\xd3" "\xd4" "\xd5" "\xd6" "\xd7" "\xd8" "\xd9" "\xda" "\xdb" "\xdc" "\xdd" "\xde" "\xdf" "";
  28. static char string_8[] = "\xe0" "\xe1" "\xe2" "\xe3" "\xe4" "\xe5" "\xe6" "\xe7" "\xe8" "\xe9" "\xea" "\xeb" "\xec" "\xed" "\xee" "\xef" "\xf0" "\xf1" "\xf2" "\xf3" "\xf4" "\xf5" "\xf6" "\xf7" "\xf8" "\xf9" "\xfa" "\xfb" "\xfc" "\xfd" "\xfe" "\xff" "";
  29. static char string_9[] = "Cancel";
  30.  
  31. static TEDINFO ascii_title =
  32.     { string_0, "", "", IBM, 0, TE_CNTR, 0x1180, 0, -1, 11, 1};
  33.  
  34. static OBJECT ascii_tree[] = {
  35.     { -1, 1, 13, G_BOX, NONE, OUTLINED,CAST (0x21141L), 0,512, 36,14 },
  36.     { 11, 2, 10, G_BOX, NONE, NORMAL,CAST (0xFF1101L), 2,3073, 32,777 },
  37.     { 3, -1, -1, (HEADER<<8)+G_BOXTEXT, NONE, NORMAL,CAST &ascii_title, 1,0, 13,1 },
  38.     { 4, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_1, 0,1, 32,1 },
  39.     { 5, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_2, 0,2, 32,1 },
  40.     { 6, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_3, 0,3, 32,1 },
  41.     { 7, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_4, 0,4, 32,1 },
  42.     { 8, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_5, 0,5, 32,1 },
  43.     { 9, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_6, 0,6, 32,1 },
  44.     { 10,-1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_7, 0,7, 32,1 },
  45.     { 1, -1, -1, G_STRING, TOUCHEXIT, NORMAL,CAST string_8, 0,8, 32,1 },
  46.     { 13, 12, 12, G_BUTTON, SELECTABLE|DEFAULT|EXIT, NORMAL,CAST string_9, 22,3851, 12,1025 },
  47.     { 11, -1, -1, (HOTKEY<<8)+G_IBOX, NONE, NORMAL,CAST (0x43011100L), 3,512, 1,1 },
  48.     { 0, -1, -1, (FLYDIAL<<8)+G_IBOX, SELECTABLE|LASTOB, NORMAL,CAST (0x57011100L), 34,0, 2,1 },
  49. };
  50.  
  51. #define ASC0    3
  52. #define CANCEL    11
  53.  
  54. static int insert_char(DIAINFO *info,int scan);
  55. static void delete_char(DIAINFO *info,int index);
  56. static void insert_string(DIAINFO *info,char *str);
  57.  
  58. char *_edit_get_info(OBJECT *tree,int obj,int index,EDINFO *ed)
  59. {
  60.     reg OBJECT *obptr;
  61.     reg TEDINFO *ted;
  62.     reg char *edit,*masc,c,u='_';
  63.     reg int x,idx,width;
  64.  
  65.     if (obj<=0 || index<0)
  66.         return (NULL);
  67.  
  68.     obptr = &tree[obj];
  69.     ted = obptr->ob_spec.tedinfo;
  70.  
  71.     if (ted->te_font==SMALL)
  72.     {
  73.         ed->cw = gr_sw;
  74.         ed->ch = gr_sh;
  75.     }
  76.     else
  77.     {
  78.         ed->cw = gr_cw;
  79.         ed->ch = gr_ch;
  80.     }
  81.  
  82.     ed->text = ted->te_ptext;
  83.     ed->masc = masc = ted->te_ptmplt;
  84.     ed->valid = ted->te_pvalid;
  85.  
  86.     width = (int) strlen(masc);
  87.     width *= ed->cw;
  88.  
  89.     objc_offset(tree,obj,&ed->text_x,&ed->text_y);
  90.     ed->text_y += (obptr->ob_height - ed->ch)>>1;
  91.     ed->text_w = width;
  92.     ed->text_h = ed->ch;
  93.  
  94.     switch(ted->te_just)
  95.     {
  96.     case TE_RIGHT:
  97.         ed->text_x += obptr->ob_width-width;
  98.         break;
  99.     case TE_CNTR:
  100.         ed->text_x += (obptr->ob_width-width)>>1;
  101.         break;
  102.     }
  103.  
  104.     ed->edit_x = ed->text_x;
  105.     ed->edit_y = ed->text_y;
  106.     ed->edit_w = 0;
  107.     ed->edit_h = ed->text_h;
  108.  
  109.     while (*masc && *masc++!=u)
  110.         ed->edit_x += ed->cw;
  111.     masc--;
  112.     edit = masc;
  113.  
  114.     width = 0;
  115.     while (*masc!='\0')
  116.     {
  117.         width += ed->cw;
  118.         if (*masc++==u)
  119.             ed->edit_w = width;
  120.     }
  121.  
  122.     x = ed->crs_x = ed->edit_x;
  123.     ed->crs_y = ed->edit_y;
  124.  
  125.     idx = 0;
  126.     masc = edit;
  127.     while ((c=*masc++)!='\0')
  128.     {
  129.         if (c==u)
  130.         {
  131.             ed->crs_x = x;
  132.             if (idx>=index)
  133.                 break;
  134.             else
  135.             {
  136.                 ed->crs_x = (x += ed->cw);
  137.                 idx++;
  138.             }
  139.         }
  140.         else
  141.             x += ed->cw;
  142.     }
  143.  
  144.     return (edit);
  145. }
  146.  
  147. static void draw_cursor(DIAINFO *info,EDINFO *ed)
  148. {
  149.     GRECT cursor,work;
  150.  
  151.     _calc_cursor(info,ed,&cursor);
  152.     if (info->di_flag>=WINDOW)
  153.     {
  154.         wind_xget(info->di_win->handle,WF_FIRSTXYWH,&work.g_x,&work.g_y,&work.g_w,&work.g_h);
  155.         while (work.g_w>0 && work.g_h>0)
  156.         {
  157.             if (rc_intersect(&cursor,&work))
  158.                 rc_sc_invert(&work);
  159.             wind_xget(info->di_win->handle,WF_NEXTXYWH,&work.g_x,&work.g_y,&work.g_w,&work.g_h);
  160.         }
  161.     }
  162.     else if (info->di_flag>CLOSED)
  163.         rc_sc_invert(&cursor);
  164. }
  165.  
  166. void _calc_cursor(DIAINFO *info,reg EDINFO *ed,reg GRECT *cursor)
  167. {
  168.     cursor->g_x = ed->crs_x;
  169.     cursor->g_y = ed->crs_y;
  170.  
  171.     if (info->di_insert)
  172.     {
  173.         cursor->g_y -= 1;
  174.         cursor->g_w = 1;
  175.         cursor->g_h = ed->ch+2;
  176.     }
  177.     else
  178.     {
  179.         cursor->g_w = ed->cw;
  180.         cursor->g_h = ed->ch;
  181.     }
  182. }
  183.  
  184. static EDINFO ed;
  185.  
  186. EDINFO *_cursor_off(DIAINFO *info)
  187. {
  188.     if (_edit_get_info(info->di_tree,info->di_ed_obj,info->di_ed_index,&ed)!=NULL)
  189.     {
  190.         if (!info->di_win->iconified && info->di_cursor)
  191.         {
  192.             graf_mouse(M_OFF,NULL);
  193.             if (info->di_flag>=WINDOW)
  194.                 wind_update(BEG_UPDATE);
  195.  
  196.             draw_cursor(info,&ed);
  197.  
  198.             if (info->di_flag>=WINDOW)
  199.                 wind_update(END_UPDATE);
  200.             graf_mouse(M_ON,NULL);
  201.         }
  202.  
  203.         info->di_cursor = FALSE;
  204.         return (&ed);
  205.     }
  206.     else
  207.         return (NULL);
  208. }
  209.  
  210. void _set_cursor(DIAINFO *info,int obj,int index)
  211. {
  212.     reg TEDINFO *ted;
  213.     reg char *masc;
  214.     reg int new_ob,len = 0;
  215.  
  216.     if (obj<0)
  217.         obj = info->di_ed_obj;
  218.  
  219.     if (info->di_win->iconified || obj<0)
  220.     {
  221.         info->di_cursor = FALSE;
  222.         return;
  223.     }
  224.  
  225.     ted = info->di_tree[obj].ob_spec.tedinfo;
  226.     if (index<0 && (index=info->di_ed_index)<0)
  227.         index = (int) strlen(ted->te_ptext);
  228.     else
  229.         index = max(min(index,(int) strlen(ted->te_ptext)),0);
  230.  
  231.     new_ob = (obj!=info->di_ed_obj);
  232.  
  233.     if (new_ob || index!=info->di_ed_index || info->di_cursor==FALSE)
  234.     {
  235.         if (new_ob)
  236.             _insert_history(info);
  237.  
  238.         graf_mouse(M_OFF,NULL);
  239.         if (info->di_flag>=WINDOW)
  240.             wind_update(BEG_UPDATE);
  241.  
  242.         if (info->di_cursor)
  243.         {
  244.             _edit_get_info(info->di_tree,info->di_ed_obj,info->di_ed_index,&ed);
  245.             draw_cursor(info,&ed);
  246.             info->di_cursor = FALSE;
  247.         }
  248.  
  249.         info->di_ed_obj = obj;
  250.         ted = info->di_tree[obj].ob_spec.tedinfo;
  251.  
  252.         if (new_ob)
  253.         {
  254.             masc = ted->te_ptmplt;
  255.             while (*masc)
  256.                 if (*masc++=='_')
  257.                     len++;
  258.             ted->te_editlen = len;
  259.         }
  260.  
  261.         if (info->di_insert==FALSE)
  262.             index = min(index,ted->te_editlen-1);
  263.  
  264.         info->di_ed_index = index;
  265.  
  266.         if (info->di_drawn)
  267.         {
  268.             _edit_get_info(info->di_tree,obj,index,&ed);
  269.             draw_cursor(info,&ed);
  270.             info->di_cursor = TRUE;
  271.         }
  272.  
  273.         if (info->di_flag>=WINDOW)
  274.             wind_update(END_UPDATE);
  275.         graf_mouse(M_ON,NULL);
  276.  
  277.         if (new_ob)
  278.             strncpy(info->di_undobuff,ob_get_text(info->di_tree,info->di_ed_obj,0),MAX_EDIT-1);
  279.     }
  280. }
  281.  
  282. static void first_edit(DIAINFO *info)
  283. {
  284.     reg OBJECT *obj = info->di_tree;
  285.     reg int index= 0;
  286.  
  287.     if (info->di_ed_cnt<=1)
  288.         return;
  289.  
  290.     do
  291.     {
  292.         obj++;index++;
  293.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  294.         {
  295.             _set_cursor(info,index,0);
  296.             break;
  297.         }
  298.     }
  299.     while (!(obj->ob_flags & LASTOB));
  300. }
  301.  
  302. static void last_edit(DIAINFO *info)
  303. {
  304.     reg OBJECT *obj = info->di_tree;
  305.     reg int index,last;
  306.  
  307.     if (info->di_ed_cnt<=1)
  308.         return;
  309.  
  310.     index = last = 0;
  311.     do
  312.     {
  313.         obj++;index++;
  314.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  315.             last = index;
  316.     }
  317.     while (!(obj->ob_flags & LASTOB));
  318.  
  319.     if (last)
  320.         _set_cursor(info,last,0x1000);
  321. }
  322.  
  323. int _next_edit(DIAINFO *info,int first)
  324. {
  325.     reg int index = info->di_ed_obj;
  326.     reg OBJECT *obj = &info->di_tree[index];
  327.  
  328.     if (info->di_ed_cnt<=1)
  329.         return(FALSE);
  330.  
  331.     if (!(obj->ob_flags & LASTOB))
  332.     {
  333.         do
  334.         {
  335.             obj++;index++;
  336.             if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  337.             {
  338.                 _set_cursor(info,index,0x1000);
  339.                 return(TRUE);
  340.             }
  341.         }
  342.         while (!(obj->ob_flags & LASTOB));
  343.     }
  344.  
  345.     if (first)
  346.     {
  347.         first_edit(info);
  348.         _set_cursor(info,FAIL,0x1000);
  349.         return (TRUE);
  350.     }
  351.     else
  352.         return (FALSE);
  353. }
  354.  
  355. static void prev_edit(DIAINFO *info)
  356. {
  357.     reg int index = info->di_ed_obj;
  358.     reg OBJECT *obj = &info->di_tree[index];
  359.  
  360.     if (info->di_ed_cnt<=1)
  361.         return;
  362.  
  363.     do
  364.     {
  365.         obj--;index--;
  366.         if ((obj->ob_flags & EDITABLE) && !_is_hidden(info->di_tree,index))
  367.         {
  368.             _set_cursor(info,index,0x1000);
  369.             return;
  370.         }
  371.     } while (index>0);
  372.  
  373.     last_edit(info);
  374. }
  375.  
  376. static int cursor_handler(DIAINFO *info,int state,int scan,XEVENT *event)
  377. {
  378.     reg char *text = ob_get_text(info->di_tree,info->di_ed_obj,0);
  379.     reg int ascii;
  380.  
  381.     if (!(state & K_CTRL))
  382.     {
  383.         if (state & 3)
  384.         {
  385.             switch(scan)
  386.             {
  387.             case SCANBS:
  388.                 if (info->di_ed_index>0)
  389.                 {
  390.                     _cursor_off(info);
  391.                     strcpy(text,&text[info->di_ed_index]);
  392.                     ob_draw_chg(info,info->di_ed_obj,NULL,FAIL,TRUE);
  393.                     _set_cursor(info,FAIL,0);
  394.                 }
  395.                 break;
  396.             case SCANDEL:
  397.                 _cursor_off(info);
  398.                 text[info->di_ed_index] = '\0';
  399.                 ob_draw_chg(info,info->di_ed_obj,NULL,FAIL,TRUE);
  400.                 _set_cursor(info,FAIL,FAIL);
  401.                 break;
  402.             case SCANRET:
  403.             case SCANENTER:
  404.             case SCANTAB:
  405.                 prev_edit(info);
  406.                 break;
  407.             case SCANUP:
  408.                 first_edit(info);
  409.                 break;
  410.             case SCANHOME:
  411.                 last_edit(info);
  412.                 break;
  413.             case SCANDOWN:
  414.                 last_edit(info);
  415.             case SCANLEFT:
  416.                 _set_cursor(info,FAIL,0);
  417.                 break;
  418.             case SCANRIGHT:
  419.                 _set_cursor(info,FAIL,0x1000);
  420.                 break;
  421.             case SCANINS:
  422.                 ascii = ascii_box(info->di_title);
  423.                 _init_xformdo(event,NULL,FAIL);
  424.                 if (ascii)
  425.                     insert_char(info,ascii);
  426.                 break;
  427.             default:
  428.                 return(FALSE);
  429.             }
  430.         }
  431.         else
  432.         {
  433.             switch(scan)
  434.             {
  435.             case SCANESC:
  436.                 insert_string(info,"");
  437.                 break;
  438.             case SCANBS:
  439.                 if (info->di_ed_index>0)
  440.                     delete_char(info,info->di_ed_index-1);
  441.                 break;
  442.             case SCANDEL:
  443.                 delete_char(info,info->di_ed_index);
  444.                 break;
  445.             case SCANHOME:
  446.                 first_edit(info);
  447.                 break;
  448.             case SCANUP:
  449.                 prev_edit(info);
  450.                 break;
  451.             case SCANDOWN:
  452.             case SCANTAB:
  453.             case SCANENTER:
  454.                 _next_edit(info,TRUE);
  455.                 break;
  456.             case SCANINS:
  457.                 _cursor_off(info);
  458.                 info->di_insert = (info->di_insert) ? FALSE : TRUE;
  459.                 _set_cursor(info,FAIL,FAIL);
  460.                 break;
  461.             case SCANLEFT:
  462.                 _set_cursor(info,FAIL,max(info->di_ed_index-1,0));
  463.                 break;
  464.             case SCANRIGHT:
  465.                 _set_cursor(info,FAIL,info->di_ed_index+1);
  466.                 break;
  467.             default:
  468.                 return(FALSE);
  469.             }
  470.         }
  471.  
  472.         return(TRUE);
  473.     }
  474.     else
  475.         return(FALSE);
  476. }
  477.  
  478. static char ted_char(char valid, reg unsigned char c)
  479. {
  480.     switch (valid)
  481.     {
  482.     case 'l':
  483.     case 'L':
  484.         if (c>=16 && c<=25)
  485.             return (c);
  486.         else if (c>='0' && c<='9')
  487.             return (c - '0' + 16);
  488.         break;
  489.     case 'c':
  490.     case 'C':
  491.         if (strchr(".+-*/^()[]{}",c))
  492.             return (c);
  493.         else if (c==',')
  494.             return ('.');
  495.     case '0':
  496.     case '1':
  497.     case '2':
  498.     case '3':
  499.     case '4':
  500.     case '5':
  501.     case '6':
  502.     case '7':
  503.     case '8':
  504.     case '9':
  505.         if (c>='0' && c<=valid)
  506.             return (c);
  507.         break;
  508.     case 'h':
  509.         c = _lower(c);
  510.         if ((c>='0' && c<='9') || (c>='a' && c<='f'))
  511.             return (c);
  512.         break;
  513.     case 'H':
  514.         c = _upper(c);
  515.         if ((c>='0' && c<='9') || (c>='A' && c<='F'))
  516.             return (c);
  517.         break;
  518.     case 'N':
  519.         if (c>='0' && c<='9')
  520.             return (c);
  521.     case 'A':
  522.         c = _upper(c);
  523.         if ((c>='A' && c<='Z') || c==' ')
  524.             return (c);
  525.         break;
  526.     case 'n':
  527.         if (c>='0' && c<='9')
  528.             return (c);
  529.     case 'a':
  530.         c = _lower(c);
  531.         if ((c>='a' && c<='z') || c==' ')
  532.             return (c);
  533.         break;
  534.     case 'P':
  535.         if (c=='\?' || c=='*')
  536.             return (c);
  537.     case 'p':
  538.         if (c=='.' || c==':' || c=='\\')
  539.             return (c);
  540.     case 'F':
  541.         if ((c>='A' && c<='Z') || (c>='a' && c<='z') || (c>='0' && c<='9') || strchr(" _!@#$%^&()+-=~\'`;\",<>|[]{}",c))
  542.             return (c);
  543.         break;
  544.     case 'U':
  545.         c = _upper(c);
  546.         if (c>=32 && c<=127)
  547.             return (c);
  548.         break;
  549.     case 'u':
  550.         c = _lower(c);
  551.         if (c>=32 && c<=127)
  552.             return (c);
  553.         break;
  554.     case 'V':
  555.         c = _upper(c);
  556.         if (c>=32)
  557.             return (c);
  558.         break;
  559.     case 'v':
  560.         c = _lower(c);
  561.         if (c>=32)
  562.             return (c);
  563.         break;
  564.     case 'w':
  565.     case 'W':
  566.         if (c>=32 && c<=127)
  567.             return (c);
  568.         break;
  569.     case 'y':
  570.     case 'Y':
  571.         if (c>=32)
  572.             return (c);
  573.         break;
  574.     case 'X':
  575.     default:
  576.         return (c);
  577.     }
  578.  
  579.     return ('\0');
  580. }
  581.  
  582. static void insert_string(DIAINFO *info,char *str)
  583. {
  584.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  585.     reg char c,v,*text = ted->te_ptext,*valid = ted->te_pvalid;
  586.     reg int len = ted->te_editlen;
  587.  
  588.     _cursor_off(info);
  589.  
  590.     v = *valid++;
  591.     while (len>0 && *str!='\0')
  592.         if ((c=ted_char(v,*str++))!='\0')
  593.         {
  594.             *text++ = c;
  595.             if (*valid)
  596.                 v = *valid++;
  597.             len--;
  598.         }
  599.     *text = '\0';
  600.  
  601.     ob_draw_chg(info,info->di_ed_obj,NULL,FAIL,FALSE);
  602.     _set_cursor(info,FAIL,0x1000);
  603. }
  604.  
  605. static void new_edit(DIAINFO *info, char *new, char *text, char *edit,int index, int len)
  606. {
  607.     char new_text[MAX_EDIT<<1],old_text[MAX_EDIT<<1];
  608.     reg EDINFO *ed;
  609.     reg char m,*s,*c,*n,*o;
  610.     reg int offset,width;
  611.     int len1,len2;
  612.  
  613.     if (strcmp(new,text))
  614.     {
  615.         n = new_text; o = old_text;
  616.         s = new; c = text;
  617.         while ((m=*edit++)!='\0')
  618.             if (m=='_')
  619.             {
  620.                 *n++ = *s++;
  621.                 *o++ = *c++;
  622.             }
  623.             else
  624.                 *n++ = *o++ = m;
  625.  
  626.         s = new_text; c = old_text;
  627.         while (*s++==*c++);
  628.  
  629.         s--;c--;
  630.         offset = (int) (s-new_text);
  631.  
  632.         len1 = (int) strlen(s);
  633.         len2 = (int) strlen(c);
  634.         if (len1!=len2)
  635.             width = max(len1,len2);
  636.         else
  637.         {
  638.             width = len1;
  639.             s += len1; c += len1;
  640.             while (*--s==*--c)
  641.                 width--;
  642.         }
  643.  
  644.         strncpy(text,new,len);
  645.  
  646.         ed = _cursor_off(info);
  647.         ed->text_x += offset*ed->cw;
  648.         ed->text_w = width*ed->cw;
  649.         ob_draw_chg(info,info->di_ed_obj,(GRECT *) &ed->text_x,FAIL,FALSE);
  650.     }
  651.  
  652.     _set_cursor(info,FAIL,index);
  653. }
  654.  
  655. static void delete_char(DIAINFO *info,int index)
  656. {
  657.     char buf[MAX_EDIT<<1];
  658.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  659.     reg char *text = ted->te_ptext;
  660.  
  661.     if (text[index]!='\0')
  662.     {
  663.         strcpy(buf,text);
  664.         strcpy(&buf[index],&text[index+1]);
  665.         new_edit(info,buf,text,ted->te_ptmplt,index,ted->te_editlen);
  666.     }
  667. }
  668.  
  669. static int insert_char(DIAINFO *info,int scan)
  670. {
  671.     char buf[MAX_EDIT<<1];
  672.     reg TEDINFO *ted = info->di_tree[info->di_ed_obj].ob_spec.tedinfo;
  673.     reg char v,*text = ted->te_ptext,*valid = ted->te_pvalid;
  674.     reg int idx,offset,taken;
  675.  
  676.     offset = idx = min(ted->te_editlen-1,info->di_ed_index);
  677.     while (idx>=0 && *valid)
  678.     {
  679.         v = *valid++;
  680.         idx--;
  681.     }
  682.  
  683.     if ((taken=ted_char(v,scan))!=0)
  684.     {
  685.         strcpy(buf,text);
  686.  
  687.         if (info->di_insert)
  688.             strcpy(&buf[offset+1],text+offset);
  689.         else
  690.         {
  691.             valid = buf;
  692.             while (*valid++);
  693.             *valid++ = '\0';
  694.         }
  695.  
  696.         buf[offset] = taken;
  697.  
  698.         new_edit(info,buf,text,ted->te_ptmplt,info->di_ed_index+1,ted->te_editlen);
  699.     }
  700.  
  701.     return (taken);
  702. }
  703.  
  704. void _insert_history(DIAINFO *info)
  705. {
  706.     reg char *str;
  707.  
  708.     if (info->di_ed_obj<=0)
  709.         return;
  710.  
  711.     str = ob_get_text(info->di_tree,info->di_ed_obj,0);
  712.  
  713.     if (str!=NULL && *str!='\0')
  714.     {
  715.         reg int i;
  716.  
  717.         for (i=0;i<HISTORY-1;i++)
  718.             if (!strcmp(history[i],str))
  719.                 return;
  720.  
  721.         for (i=(HISTORY-1);i>=1;i--)
  722.             strcpy(history[i],history[i-1]);
  723.  
  724.         strcpy(history[0],str);
  725.  
  726.         if (hist_index<(HISTORY-1) && history[hist_index+1][0])
  727.             hist_index++;
  728.     }
  729. }
  730.  
  731. static boolean clipbrd_save(DIAINFO *info,int mode)
  732. {
  733.     char path[256],buf[MAX_EDIT+4],*text=ob_get_text(info->di_tree,info->di_ed_obj,0);
  734.     long len;
  735.     int handle;
  736.  
  737.     scrp_read(path);
  738.     if (*path)
  739.     {
  740.         _strmfp(path,NULL,"scrap.txt");
  741.         if ((handle = open(path,mode))>0)
  742.         {
  743.             len = strlen(text);
  744.             strcpy(buf,text);
  745.             buf[len++] = '\r';
  746.             buf[len++] = '\n';
  747. #ifdef __MINT_LIB__
  748.             write(handle,buf,(unsigned) len);
  749. #else
  750.             write(handle,buf,len);
  751. #endif
  752.             close(handle);
  753.             scrp_changed(SCF_TEXT,0x2e545854l);    /* .TXT */
  754.             return(TRUE);
  755.         }
  756.     }
  757.     return(FALSE);
  758. }
  759.  
  760. static void clipbrd_load(DIAINFO *info,boolean flag)
  761. {
  762.     char path[256],buf[MAX_EDIT];
  763.     int handle;
  764.  
  765.     scrp_read(path);
  766.     if (path[0]!='\0')
  767.     {
  768.         _strmfp(path,NULL,"scrap.txt");
  769.         if ((handle = open(path,O_RDONLY))>0)
  770.         {
  771.             if (read(handle,buf,MAX_EDIT-1)>0);
  772.             {
  773.                 reg char *line;
  774.  
  775.                 buf[MAX_EDIT-1] = '\0';
  776.                 if ((line = strchr(buf,'\r'))!=NULL || (line = strchr(buf,'\n'))!=NULL)
  777.                     *line = '\0';
  778.  
  779.                 if (flag)
  780.                 {
  781.                     char str[MAX_EDIT<<1];
  782.  
  783.                     strcpy(str,ob_get_text(info->di_tree,info->di_ed_obj,0));
  784.                     strcat(str,buf);
  785.                     strncpy(buf,str,MAX_EDIT-1);
  786.                 }
  787.  
  788.                 insert_string(info,buf);
  789.             }
  790.             close(handle);
  791.         }
  792.     }
  793. }
  794.  
  795. static boolean word_char(char c)
  796. {
  797.     if (c)
  798.         if (isalnum(c) || strchr(umlaute,c)!=NULL)
  799.             return(TRUE);
  800.     return(FALSE);
  801. }
  802.  
  803. static int value[] = {7,8,9,4,5,6,1,2,3,0};
  804.  
  805. int _objc_edit_handler(DIAINFO *info,int state,int scan,XEVENT *event,int *edited)
  806. {
  807.     reg int old_obj = info->di_ed_obj;
  808.     reg int sn = (int) (((unsigned) scan)>>8),shft = (state&3);
  809.     reg char old_edit[MAX_EDIT],*text = ob_get_text(info->di_tree,old_obj,0);
  810.  
  811.     strcpy(old_edit,text);
  812.  
  813.     info->di_taken = TRUE;
  814.     if (cursor_handler(info,state,sn,event)==FALSE)
  815.     {
  816.         if (sn==SCANUNDO)
  817.             insert_string(info,info->di_undobuff);
  818.         else if ((state & K_ALT) && (sn>=0x67 && sn<=0x70))
  819.         {
  820.             _ascii *= 10;
  821.             _ascii += value[sn-0x67];
  822.             _ascii_digit++;
  823.             if (_ascii_digit==3 || _ascii>=26)
  824.             {
  825.                 insert_char(info,_ascii);
  826.                 _ascii = _ascii_digit = 0;
  827.             }
  828.         }
  829.         else if (state & K_CTRL)
  830.         {
  831.             reg char *c    = text+info->di_ed_index;
  832.  
  833.             switch (sn)
  834.             {
  835.             case CTRLLEFT:
  836.                 while (c>text && word_char(*(--c)));
  837.                 while (c>text && !word_char(*(--c)));
  838.                 _set_cursor(info,FAIL,(c>text) ? (int) (c - text + 1) : 0);
  839.                 break;
  840.             case CTRLRIGHT:
  841.                 while (word_char(*c++));
  842.                 if (*(--c) != '\0')
  843.                 {
  844.                     while (!word_char(*c++));
  845.                     if (*(--c) != '\0')
  846.                         _set_cursor(info,FAIL,(int) (c - text));
  847.                 }
  848.                 else
  849.                     _set_cursor(info,FAIL,(int) (c - text));
  850.                 break;
  851.             case SCANUP:
  852.                 {
  853.                     int o_i = hist_index;
  854.                     _insert_history(info);
  855.                     if (shft)
  856.                     {
  857.                         reg size_t n = strlen(text);
  858.                         if (n)
  859.                         {
  860.                             reg int i;
  861.                             for (i=(hist_index!=o_i) ? 1 : 0;i<HISTORY;i++)
  862.                                 if (!strncmp(history[i],text,n))
  863.                                 {
  864.                                     insert_string(info,history[i]);
  865.                                     hist_index = i;
  866.                                     break;
  867.                                 }
  868.                         }
  869.                     }
  870.                     else
  871.                     {
  872.                         if ((hist_index<(HISTORY-1)) && (history[hist_index+1][0]))
  873.                             hist_index++;
  874.                         insert_string(info,history[hist_index]);
  875.                     }
  876.                 }
  877.                 break;
  878.             case SCANDOWN:
  879.                 _insert_history(info);
  880.                 if (shft)
  881.                 {
  882.                     reg size_t n = strlen(text);
  883.                     if (n)
  884.                     {
  885.                         reg int i;
  886.                         for (i=(HISTORY-1);i>=0;i--)
  887.                             if (!strncmp(history[i],text,n))
  888.                             {
  889.                                 insert_string(info,history[i]);
  890.                                 hist_index = i;
  891.                                 break;
  892.                             }
  893.                     }
  894.                 }
  895.                 else
  896.                 {
  897.                     if (hist_index>0 && history[hist_index-1][0])
  898.                         hist_index--;
  899.                     insert_string(info,history[hist_index]);
  900.                 }
  901.                 break;
  902.             default:
  903.                 {
  904.                     int ascii = scan_2_ascii(scan,state),flag;
  905.  
  906.                     switch (ascii)
  907.                     {
  908.                     case 'X':
  909.                     case 'C':
  910.                         if (shft)
  911.                             flag = clipbrd_save(info,O_WRONLY|O_APPEND|O_CREAT);
  912.                         else
  913.                         {
  914.                             scrp_clear(0);
  915.                             flag = clipbrd_save(info,O_WRONLY|O_CREAT);
  916.                         }
  917.  
  918.                         if (flag && ascii=='X')
  919.                         {
  920.                             _cursor_off(info);
  921.                             ob_get_text(info->di_tree,info->di_ed_obj,1);
  922.                             ob_draw_chg(info,info->di_ed_obj,NULL,FAIL,TRUE);
  923.                             _set_cursor(info,FAIL,FAIL);
  924.                         }
  925.                         break;
  926.                     case 'V':
  927.                         clipbrd_load(info,(shft) ? TRUE : FALSE);
  928.                         break;
  929.                     default:
  930.                         info->di_taken = FALSE;
  931.                         break;
  932.                     }
  933.                 }
  934.                 break;
  935.             }
  936.         }
  937.         else
  938.             info->di_taken = insert_char(info,scan);
  939.     }
  940.  
  941.     if (info->di_taken && old_obj==info->di_ed_obj && strcmp(old_edit,text))
  942.         *edited = TRUE;
  943.     else
  944.         *edited = FALSE;
  945.  
  946.     return(FAIL);
  947. }
  948.  
  949. char ascii_box(char *title)
  950. {
  951.     static int fix = TRUE;
  952.     int exit;
  953.  
  954.     if (fix)
  955.     {
  956.         rsrc_calc(ascii_tree,SCALING,8,16);
  957.         fix = FALSE;
  958.     }
  959.  
  960.     exit = xdialog(ascii_tree,title,TRUE,FALSE,AUTO_DIAL|MODAL);
  961.  
  962.     if (exit>0)
  963.     {
  964.         if (exit!=CANCEL)
  965.         {
  966.             int x,ox,d,ascii;
  967.  
  968.             _mouse_pos(&x,&d);
  969.             objc_offset(ascii_tree,exit,&ox,&d);
  970.             _no_click();
  971.  
  972.             ascii = (exit - ASC0)<<5;
  973.             if ((d = x-ox)>=0)
  974.                 ascii += d/gr_cw;
  975.             ascii = min(max(ascii,0),255);
  976.  
  977.             return(ascii);
  978.         }
  979.     }
  980.  
  981.     return(0);
  982. }
  983.